#include "game.h"

polaris::logic::logic(polaris::window *iwin, polaris::player *ip1, polaris::player **ibackgrounds)
{
    win = iwin;
    w = win->screen->w;
    h = win->screen->h;

    p1 = ip1;

    background = ibackgrounds;

    music = new polaris::sound("sound/cannon.wav");

    dozer = false;
}


void polaris::logic::doInputs(int whichplayer)
{

    switch(whichplayer)
    {
        case 1:

            if(win->playerControls.cursorup) p1->forceY-=0.1;
            else if(win->playerControls.cursordown) p1->forceY+=0.1;
            else  p1->forceY/=1.04;

            if(win->playerControls.cursorleft) p1->forceX-=0.1;
            else if(win->playerControls.cursorright) p1->forceX+=0.1;
            else  p1->forceX/=2;

        break;


        case 2:

            if(win->playerControls2.cursorup) p1->forceY-=0.1;
            else if(win->playerControls2.cursordown) p1->forceY+=0.1;
            else  p1->forceY/=1.04;

            if(win->playerControls2.cursorleft) p1->forceX-=0.1;
            else if(win->playerControls2.cursorright) p1->forceX+=0.1;
            else  p1->forceX/=2;

        break;


        default:
            cout << "Invalid Player ID\n";
            exit(-1);
        break;
    }


}

void polaris::logic::drawObstacles(polaris::player *opp)
{//int count =0;
    for(double j=-40; j<40; j+=1)
    {

        /* setup player rotation */
            double nx = sin((j+p1->viewposX)/100);
                double ny = cos((j+p1->viewposX)/100);
                /* ..and look forward */
                double px = (nx*1/10);
                double py = (ny*1/10);


        double x = p1->posX;
        double y = p1->posY;

        for(int i=1; i<200; i++)
        {
            x+=px;
            y-=py;
            //cout <<p1->posX << " " << p1->posY<< " " << x << " " << y << endl;
            //city[(int)y  +  (int)x*citysize] = 2;
            if(x>0 && y>0 && x<citysize && y<citysize)
            {
                    /* obstacle found, calculate range */
                    if(city[ (int)y  +  (int)x*citysize]==0)
                    {
                        //double range = sqrt( pow(p1->posX-x,2) + pow(p1->posY -y,2));
                        int px = (int)(win->screen->w/2+j*8);
                        int py = win->screen->h/2 + win->screen->h/3 -i/3 -40 ;
                        if(py>win->screen->h/2)
                        {
                            int mh = 300-i;
                            for(int h=0; h<mh; h++)
                            {
                                int oy = py-h;

                                int color = (250-i  + mh-50)/2;

                                for(int fill = 0; fill<8; fill++) win->DrawPixel(px+fill, oy, color, color,color);

                            }
                        }
                        //cout << range << endl;
                        //cout << p1->posX-x << " " << p1->posY-y << endl;
                        //count++;
                        break;
                    }
                    else if(city[ (int)y  +  (int)x*citysize]==10)
                    {
                        //double range = sqrt( pow(p1->posX-x,2) + pow(p1->posY -y,2));
                        int px = (int)(win->screen->w/2+j*8);
                        int py = win->screen->h/2 + win->screen->h/3 -i/3 -40 ;
                        if(py>win->screen->h/2)
                        {
                            int mh = 300-i;
                            for(int h=0; h<mh/2; h++)
                            {
                                int oy = py-h;

                                int color = (250-i  + mh-50)/2;

                                for(int fill = 0; fill<2; fill++) win->DrawPixel(px+fill, oy, color/2, color,0);

                            }
                        }
                        //cout << range << endl;
                        //cout << p1->posX-x << " " << p1->posY-y << endl;
                        //count++;
                        break;
                    }
                    else if(city[ (int)y  +  (int)x*citysize]==3)
                    {
                        //double range = sqrt( pow(p1->posX-x,2) + pow(p1->posY -y,2));
                        int px = (int)(win->screen->w/2+j*8);
                        int py = win->screen->h/2 + win->screen->h/3 -i/3 -40 ;
                        if(py>win->screen->h/2)
                        {
                            int mh = 300-i;
                            for(int h=0; h>-mh/20; h--)
                            {
                                int oy = py-h;

                                int color = (250-i  + mh-50)/2;

                                for(int fill = 0; fill<8; fill++) win->DrawPixel(px+fill, oy, color/2, color/2,color/2);

                            }
                        }
                        //cout << range << endl;
                        //cout << p1->posX-x << " " << p1->posY-y << endl;
                        //count++;
                       // break;
                    }
                    else if( (int)x==(int)opp->posX &&  (int)y==(int)opp->posY)
                    {
                            int px = (int)(win->screen->w/2+j*8);
                            int py = win->screen->h/2 + win->screen->h/3 -i/3 -40 ;
                            if(py>win->screen->h/2)
                            {
                                    int mh = 300-i;
                                    for(int h=0; h<mh/2; h++)
                                    {
                                        int oy = py-h;

                                        int color = 250-i/2;

                                        for(int fill = 0; fill<8; fill++) win->DrawPixel(px+fill, oy, color, 0,0);
                                    }
                            }
                            break;
                    }
            }
        }
//cout << count << endl;

    }

}


void polaris::logic::drawBackgrounds()
{
    /* blit citys, first modulo, to wrap around, then blit each one tree times,
    center, left and right.
    */
    if(background[0]->posX>background[0]->w) background[0]->posX = 0;
    if(background[1]->posX>background[1]->w) background[1]->posX = 0;

    if(background[0]->posX<-background[0]->w) background[0]->posX = 0;
    if(background[1]->posX<-background[1]->w) background[1]->posX = 0;

    win->setImg(background[0]);
    win->setImg(background[0]->gfx, (int) background[0]->posX-(int)background[0]->w, (int)background[0]->posY );
    win->setImg(background[0]->gfx, (int)background[0]->posX+(int)background[0]->w, (int)background[0]->posY );

    win->setImg(background[1]);
    win->setImg(background[1]->gfx, (int)background[1]->posX-(int)background[1]->w, (int)background[1]->posY );
    win->setImg(background[1]->gfx, (int)background[1]->posX+(int)background[1]->w, (int)background[1]->posY );
}


void polaris::logic::drawEnviroment()
{
    /* setup screen */
    win->clear();

    /* draw sky */
    for(int i=0; i<h/2; i++)
    {
        int col = (int)((double)155/(double)h*(double)2 * (double)i);
        int col2 = (int)((double)100/(double)(citysize) * p1->posY);
         for(int j=0; j<w; j++)
         {
            win->DrawPixel(j,i, 10+col/2,50+col/2,100+col-col2);
         }
    }

    /* draw ground */
    int counter = 0;
    int groundcolor1 = 100;
    int groundcolor2 = 140;

    double sizestep = 3;
    double stepgrowrate = 0.2;

    for(int i=h/2; i<h; i++)
    {
        double g = sin(0.4*i/ sizestep -p1->viewposY/40);

        int col = (int)((double)100/(double)(citysize) * p1->posY);
        int col2 = (int)((double)100/(double)(citysize) * p1->posX);

        if(g>=0) g=groundcolor1;
        else g= groundcolor2;

        sizestep += stepgrowrate;

        for(int j=0; j<w; j++)
         {
             win->DrawPixel(j,i, col2,(int)g-((col+col2)/2),col);
         }
    }
}


void polaris::logic::doPhysics()
{
    /* pull max velocity to maximum value */
    double maximumvelocityY = 4;
    double maximumvelocityX = 4;
    if(p1->forceX>maximumvelocityX) p1->forceX=maximumvelocityX;
    if(p1->forceX<-maximumvelocityX) p1->forceX=-maximumvelocityX;
    if(p1->forceY>maximumvelocityY) p1->forceY=maximumvelocityY;
    if(p1->forceY<-maximumvelocityY) p1->forceY=-maximumvelocityY;


/* cost */
// if(abs((int)p1->forceY)>1) p1->forceY/=((double)city[(int)p1->posY + (int)p1->posX*citysize]+1);

//cout << p1->forceY<<" " <<city[(int)p1->posY + (int)p1->posX*citysize] << endl;

    /* physics handling setup offsetY,
    which is used in the sine-function to draw ground
    */
    p1->viewposX+=p1->forceX;
    p1->viewposY+=p1->forceY;

    /* setup player rotation */
    double nx = sin(p1->viewposX/100);
    double ny = cos(p1->viewposX/100);
    /* ..and drive forward, if there is no obstacle */

    double plastx = p1->posX;
    double plasty = p1->posY;



    p1->posX -= (nx*p1->forceY/10);
    p1->posY += (ny*p1->forceY/10);

if(city[(int)p1->posY + (int)p1->posX*citysize]==0 && !dozer)
{
    p1->posX = plastx;
    p1->posY = plasty;
    p1->forceY *= -1 ;
    music->play();
}
else if(city[(int)p1->posY + (int)p1->posX*citysize]==0 && dozer)
{
    if(abs((int)p1->forceY)>=1)
    {
        city[(int)p1->posX*citysize +(int)p1->posY]++;
    }
    else
    {
        p1->posX = plastx;
        p1->posY = plasty;
    }
   // cout << p1->forceY << endl;
    p1->forceY = 0 ;
    music->play();

}
//else if(dozer)
{
   //city[(int)p1->posX*citysize +(int)p1->posY]++;
}


    /* drive around borders */
    if(p1->posX>citysize) p1->posX = 0;
    if(p1->posX<0) p1->posX = citysize;

    if(p1->posY>citysize) p1->posY = 0;
    if(p1->posY<0) p1->posY = citysize;


    /* background handling, city will move, when player moves */
    background[0]->posY = h/2-background[1]->h;
    background[1]->posY = h/2-background[1]->h;

    background[0]->posX -= (int)p1->forceX*2;
    background[1]->posX -= (int)p1->forceX*4;

    //if(dozer) { if(abs((int)p1->forceY)>1) city[(int)p1->posY +(int)p1->posX*citysize]++ ; }

}

void polaris::logic::generateCity(int *icity, int icitysize)
{
    city = icity;
    citysize = icitysize;

    for(int i=0; i<citysize*citysize; i++)
    {
        if(rand()%30==0) city[i] = 0;
        else if(rand()%2090==0) city[i] = 10;
        //else if(rand()%30==0) city[i] = 3;
        else city[i] = 1;
    }

    for(int i=0; i<citysize; i++)
    {
         for(int j=0; j<citysize; j++)
        {
            int bug = 30;
            int blevel = 2;

            if(i>bug &&j>bug && i+bug<citysize-1 && j+bug<citysize-1)  city[i +j*citysize] = 0;
            if(i> citysize/2-blevel && i< citysize/2+blevel) city[i +j*citysize] = 1;
            if(j> citysize/2-blevel && j< citysize/2+blevel) city[i +j*citysize] = 1;


            if(i==0 || j==0 || i==citysize-1 || j==citysize-1)  city[i +j*citysize] = 0;
        }
    }

}


void polaris::logic::drawMinimap(int u, int v, int r, int g, int b, int counter, polaris::player *opponent)
{
    /* draw minimap */
    for(int x=0; x<citysize; x++)
    {
        for(int y=0; y<citysize; y++)
        {
            /*if(x==p1->posY && y==p1->posX) cout << "X";
            else cout << city[y+x*citysize];*/
            int cell = 3;

            for(int dx=x*cell; dx<cell-1 +cell*x; dx++)
            {
                for(int dy=y*cell; dy<cell-1 +cell*y; dy++)
                {
                    /* obstacle = 0 */
                    if(city[y+x*citysize]==0) win->DrawPixel(u+dx,v+dy,0,0,0);
                    else if(city[y+x*citysize]==10) win->DrawPixel(u+dx,v+dy,255,255,0);
                    else if(city[y+x*citysize]==3) win->DrawPixel(u+dx,v+dy,255,255,255);
                    else
                    {
                        win->DrawPixel(u+dx,v+dy, 100,100,100);
                    }

                    /* draw border */
                    if(dx>=citysize*cell-2 || dy>=citysize*cell-2  || dy>=y*citysize*cell-2 || dx>=x*citysize*cell-2) win->DrawPixel(u+dx,v+dy,0,0,0);

                    /* draw player */
                    if(y==(int)p1->posY && x==(int)p1->posX && counter%2==0)
                    {
                        win->DrawPixel(u+dx,v+dy,r,g,b);
                        win->DrawPixel(u+dx+1,v+dy,r,g,b);
                        win->DrawPixel(u+dx,v+dy+1,r,g,b);
                        win->DrawPixel(u+dx+1,v+dy+1,r,g,b);
                    }
                    else if(y==(int)p1->posY && x==(int)p1->posX && counter%2==1)
                    {
                        win->DrawPixel(u+dx,v+dy,255,255,255);
                        win->DrawPixel(u+dx+1,v+dy,255,255,255);
                        win->DrawPixel(u+dx,v+dy+1,255,255,255);
                        win->DrawPixel(u+dx+1,v+dy+1,255,255,255);
                    }
                    //else if(y==(int)p1->posY || x==(int)p1->posX) win->DrawPixel(u+dx,v+dy,r/2,g/2,b/2);

        /* draw opponent */
                    if(y==(int)opponent->posY && x==(int)opponent->posX && counter%2==0)
                    {
                        win->DrawPixel(u+dx,v+dy,0,100,255);
                        win->DrawPixel(u+dx+1,v+dy,0,1000,255);
                        win->DrawPixel(u+dx,v+dy+1,0,100,255);
                        win->DrawPixel(u+dx+1,v+dy+1,0,100,255);
                    }
                    else if(y==(int)opponent->posY && x==(int)opponent->posX && counter%2==1)
                    {
                        win->DrawPixel(u+dx,v+dy,255,255,255);
                        win->DrawPixel(u+dx+1,v+dy,255,255,255);
                        win->DrawPixel(u+dx,v+dy+1,255,255,255);
                        win->DrawPixel(u+dx+1,v+dy+1,255,255,255);
                    }


                }
            }
        }
        //cout << endl;
    }
}
